
/**
@file ctc_mirror_cli.c

@date 2020-08-04

@version v1.0

---file comments----
*/


/****************************************************************
*
* Header Files
*
***************************************************************/
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "ctc_asw_common.h"
#include "ctcs_api.h"


extern int32 _ctc_asw_chip_get_cpu_port(uint8 lchip);

CTC_CLI(ctc_cli_asw_mirror_set_port_enable,
        ctc_cli_asw_mirror_set_port_enable_cmd,
        "mirror source port (GPHYPORT_ID |cpu ) (gchip GCHIP|) direction (ingress | egress | both) (enable session SESSION_ID | disable)",
        CTC_CLI_MIRROR_M_STR,
        "Mirror source, port or vlan",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Network cpu port or dma cpu channel",
        "Gchip",
        "Gchip ID",
        "The direction of monitored traffic",
        "Mirror received traffic",
        "Mirror transmitted traffic",
        "Mirror received and transmitted traffic",
        "Mirror enable",
        "Configure a mirror session",
        "Session_id range <0-3>, cpu mirror don't care session id",
        "Mirror disable")
{
    uint8 session_id = 0;
    uint32 gport;
    uint8  gchip = 0;
    ctc_direction_t dir = CTC_INGRESS;
    int32 ret  = CLI_SUCCESS;
    uint8 index = 0xFF;

    index = CTC_CLI_GET_ARGC_INDEX("gchip");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8("gchip", gchip, argv[index + 1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX("cpu");
    if (0xFF != index)
    {
        gport = _ctc_asw_chip_get_cpu_port(g_api_lchip);
    }
    else
    {
        CTC_CLI_GET_UINT32("gport", gport, argv[0]);
    }

    /*parse direction*/
    index = CTC_CLI_GET_ARGC_INDEX("ingress");
    if (0xFF != index)
    {
        dir = CTC_INGRESS;
    }
    index = CTC_CLI_GET_ARGC_INDEX("egress");
    if (0xFF != index)
    {
        dir = CTC_EGRESS;
    }
    index = CTC_CLI_GET_ARGC_INDEX("both");
    if (0xFF != index)
    {
        dir = CTC_BOTH_DIRECTION;
    }
    /*parse session*/
    index = CTC_CLI_GET_ARGC_INDEX("session");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("session id", session_id, argv[index + 1],
                                0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("enable");
    if (0xFF != index)
    {
        ret = ctcs_mirror_set_port_en(g_api_lchip, gport, dir, TRUE, session_id);
    }

    index = CTC_CLI_GET_ARGC_INDEX("disable");
    if (0xFF != index)
    {
        ret = ctcs_mirror_set_port_en(g_api_lchip, gport, dir, FALSE, session_id);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}


CTC_CLI(ctc_cli_asw_mirror_add_session,
        ctc_cli_asw_mirror_add_session_cmd,
        "mirror destination add session SESSION_ID direction (ingress|egress|both) (port-session | \
        acl-session (priority-id PRIORITY_ID|) )  (port GPORT_ID) ",
        CTC_CLI_MIRROR_M_STR,
        "Mirror destination",
        "Add destination for mirror session",
        "Configure a mirror session",
        "Session_id range <0-3>",
        "The direction of monitored traffic",
        "Mirror received traffic",
        "Mirror transmitted traffic",
        "Mirror received and transmitted traffic",
        "Port session",
        "Acl session",
        "Acl priority id",
        "Useless for ax",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC
     )
{
    ctc_mirror_dest_t mirror;
    int32 ret  = CLI_SUCCESS;
    uint8 index = 0xFF;

    sal_memset(&mirror, 0, sizeof(ctc_mirror_dest_t));

    /*parse dest_gport*/
    index = CTC_CLI_GET_SPECIFIC_INDEX("port", 3);
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32_RANGE("gport", mirror.dest_gport, argv[index + 4],
                                 0, CTC_MAX_UINT32_VALUE);
    }

    ret = ctcs_mirror_add_session(g_api_lchip, &mirror);

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_mirror_remove_session,
        ctc_cli_asw_mirror_remove_session_cmd,
        "mirror destination remove session SESSION_ID direction (ingress|egress|both) (port-session | acl-session (priority-id PRIORITY_ID|))",
        CTC_CLI_MIRROR_M_STR,
        "Mirror destination",
        "Remove mirror destination",
        "Configure a mirror session",
        "Session_id range <0-3>",
        "The direction of monitored traffic",
        "Mirror received traffic",
        "Mirror transmitted traffic",
        "Mirror received and transmitted traffic",
        "Port session",
        "Acl session",
        "Acl priority id",
        "Useless for ax")
{
    ctc_mirror_dest_t mirror;
    int32 ret  = CLI_SUCCESS;
    sal_memset(&mirror, 0, sizeof(ctc_mirror_dest_t));

    ret = ctcs_mirror_remove_session(g_api_lchip, &mirror);

    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;

}

CTC_CLI(ctc_cli_asw_mirror_show_port_mirror_state,
        ctc_cli_asw_mirror_show_port_mirror_state_cmd,
        "show mirror port GPHYPORT_ID direction (ingress|egress) ",
        CTC_CLI_SHOW_STR,
        CTC_CLI_MIRROR_M_STR,
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "The direction of monitored traffic",
        "Mirror received traffic",
        "Mirror transmitted traffic")
{
    uint32 gport;
    ctc_direction_t dir;
    bool enable;
    int32 ret  = CLI_SUCCESS;

    /*parse port*/
    CTC_CLI_GET_UINT32("gport", gport, argv[0]);

    if (0 == sal_memcmp(argv[1], "in", 2))
    {
        dir = CTC_INGRESS;
    }
    else
    {
        dir = CTC_EGRESS;
    }

    ret = ctcs_mirror_get_port_info(g_api_lchip, gport, dir, &enable, NULL);
    if (ret < 0)
    {
        ctc_cli_out("%% %s \n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("show gport=0x%.4x mirror state\n", gport);
    ctc_cli_out("===================================\n");
    ctc_cli_out("mirror enable                   :%d\n", enable);
    ctc_cli_out("===================================\n");

    return ret;
}

int32
ctc_asw_mirror_cli_init(uint8 cli_tree_mode)
{
    install_element(cli_tree_mode, &ctc_cli_asw_mirror_set_port_enable_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_mirror_add_session_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_mirror_remove_session_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_mirror_show_port_mirror_state_cmd);
    return CLI_SUCCESS;
}
